package com.qiujie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiujie.dto.Response;
import com.qiujie.dto.ResponseDTO;
import com.qiujie.entity.DailyMenu;
import com.qiujie.entity.DiningOrder;
import com.qiujie.entity.ElderlyInfo;
import com.qiujie.entity.Staff;
import com.qiujie.enums.BusinessStatusEnum;
import com.qiujie.exception.ServiceException;
import com.qiujie.mapper.DiningOrderMapper;
import com.qiujie.service.DailyMenuService;
import com.qiujie.service.DiningOrderService;
import com.qiujie.service.ElderlyInfoService;
import com.qiujie.service.StaffService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订餐Service实现类
 */
@Service
public class DiningOrderServiceImpl extends ServiceImpl<DiningOrderMapper, DiningOrder> implements DiningOrderService {

    @Autowired
    private DailyMenuService dailyMenuService;
    
    @Autowired
    private StaffService staffService;

    @Autowired
    private DiningOrderMapper diningOrderMapper;
    

    @Override
    public ResponseDTO create(DiningOrder diningOrder) {
        // 验证老人用户是否存在
        Staff elderlyStaff = staffService.getById(diningOrder.getStaffId());
        if (elderlyStaff == null) {
            return Response.error("老人用户不存在");
        }

        // 验证下单用户是否存在
        Staff staff = staffService.getById(diningOrder.getStaffId());
        if (staff == null) {
            return Response.error("下单用户不存在");
        }
        
        // 生成订单编号
        String orderNo = "ORDER-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
        diningOrder.setOrderNo(orderNo);
        
        // 默认待确认状态
        diningOrder.setStatus(1);


        diningOrder.setOrderDate(Timestamp.valueOf(LocalDateTime.now()));
        diningOrder.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
        diningOrder.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));
        diningOrder.setDeleteFlag(0);
        if (elderlyStaff.getBalance()<diningOrder.getPrice()){
            throw new ServiceException(BusinessStatusEnum.INSUFFICIENT_AMOUNT);
        }

        // 设置价格(此处为示例，实际应根据饮食价格计算)
        diningOrder.setPrice(diningOrder.getPrice());

        boolean result = this.save(diningOrder);
        return result ? Response.success(diningOrder.getId()) : Response.error("订餐失败");
    }

    @Override
    public ResponseDTO statistics() {
        // 1. 计算开始/结束日期
        LocalDate endDate = LocalDate.now();
        LocalDate startDate = endDate.minusDays(6);
        DateTimeFormatter dbFmt  = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter outFmt = DateTimeFormatter.ofPattern("MM-dd");

        // 2. 一次性按 order_date 分组查询
        List<Map<String, Object>> rawList = diningOrderMapper.selectMaps(
                new QueryWrapper<DiningOrder>()
                        .select("DATE_FORMAT(order_date, '%Y-%m-%d') AS date", "COUNT(*) AS cnt")
                        .ge("order_date", startDate.format(dbFmt))
                        .le("order_date", endDate.format(dbFmt))
                        .groupBy("DATE_FORMAT(order_date, '%Y-%m-%d')")
        );
        Map<String, Long> cntMap = rawList.stream()
                .collect(Collectors.toMap(
                        m -> m.get("date").toString(),
                        m -> ((Number)m.get("cnt")).longValue()
                ));

        // 3. 补齐最近7天的数据
        List<String> dates = new ArrayList<>(7);
        List<Integer> counts = new ArrayList<>(7);
        for (int i = 0; i < 7; i++) {
            LocalDate d = startDate.plusDays(i);
            String key = d.format(dbFmt);
            dates.add(d.format(outFmt));
            counts.add(cntMap.getOrDefault(key, 0L).intValue());
        }

        // 4. 直接用 Map 封装
        Map<String, Object> data = new HashMap<>(2);
        data.put("dates", dates);
        data.put("counts", counts);

        // 5. 返回给前端
        return new ResponseDTO(200, "统计成功", data, null);
    }

    @Override
    public ResponseDTO cancel(Integer id) {
        DiningOrder order = this.getById(id);
        if (order == null) {
            return Response.error("订单不存在");
        }
        
        // 已确认的订单不能取消
        if (order.getStatus() == 2) {
            return Response.error("已确认的订单不能取消");
        }
        
        // 已取消的订单不能再次取消
        if (order.getStatus() == 0) {
            return Response.error("订单已取消");
        }
        
        order.setStatus(0);
        order.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));
        
        boolean result = this.updateById(order);
        return result ? Response.success() : Response.error("取消失败");
    }

    @Override
    public ResponseDTO confirm(Integer id) {
        DiningOrder order = this.getById(id);
        if (order == null) {
            return Response.error("订单不存在");
        }
        
        // 已取消的订单不能确认
        if (order.getStatus() == 0) {
            return Response.error("已取消的订单不能确认");
        }
        
        // 已确认的订单不能再次确认
        if (order.getStatus() == 2) {
            return Response.error("订单已确认");
        }
        
        order.setStatus(2);
        order.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));

        // 更新用户金额
        Integer staffId = order.getStaffId();
        Staff elderlyStaff = staffService.getById(staffId);

        if (elderlyStaff.getBalance()<order.getPrice()||elderlyStaff.getBalance()==0){
            throw new ServiceException(BusinessStatusEnum.INSUFFICIENT_AMOUNT);
        }
        elderlyStaff.setBalance(elderlyStaff.getBalance()-order.getPrice());
        staffService.updateById(elderlyStaff);
        boolean result = this.updateById(order);
        return result ? Response.success() : Response.error("确认失败");
    }

    @Override
    public ResponseDTO list(Integer elderlyStaffId, Integer staffId, Integer status, Date startDate, Date endDate) {
        LambdaQueryWrapper<DiningOrder> queryWrapper = new LambdaQueryWrapper<>();
        
        if (elderlyStaffId != null) {
            queryWrapper.eq(DiningOrder::getElderlyStaffId, elderlyStaffId);
        }
        
        if (staffId != null) {
            queryWrapper.eq(DiningOrder::getStaffId, staffId);
        }
        
        if (status != null) {
            queryWrapper.eq(DiningOrder::getStatus, status);
        }
        
        if (startDate != null) {
            queryWrapper.ge(DiningOrder::getOrderDate, startDate);
        }
        
        if (endDate != null) {
            queryWrapper.le(DiningOrder::getOrderDate, endDate);
        }
        
        queryWrapper.orderByDesc(DiningOrder::getCreateTime);
        
        List<DiningOrder> list = this.list(queryWrapper);
        return Response.success(list);
    }

    @Override
    public ResponseDTO getDetail(Integer id) {
        DiningOrder order = this.getById(id);
        if (order == null) {
            return Response.error("订单不存在");
        }
        
        // 获取菜单和用户信息
        DailyMenu menu = dailyMenuService.getById(order.getMenuId());
        Staff elderlyStaff = staffService.getById(order.getElderlyStaffId());
        Staff staff = staffService.getById(order.getStaffId());
        
        Map<String, Object> result = new HashMap<>();
        result.put("order", order);
        result.put("menu", menu);
        result.put("elderlyStaff", elderlyStaff);
        result.put("staff", staff);
        
        return Response.success(result);
    }

    @Override
    public ResponseDTO getStatistics(Date startDate, Date endDate) {
        // 如果未指定日期，则默认查询当天
        if (startDate == null) {
            startDate = Date.valueOf(LocalDate.now());
        }
        
        if (endDate == null) {
            endDate = Date.valueOf(LocalDate.now());
        }
        
        LambdaQueryWrapper<DiningOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.between(DiningOrder::getOrderDate, startDate, endDate);
        
        // 统计各状态订单数量
        Map<String, Object> result = new HashMap<>();
        
        // 总订单数
        long total = this.count(queryWrapper);
        result.put("total", total);
        
        // 已取消订单数
        queryWrapper.clear();
        queryWrapper.between(DiningOrder::getOrderDate, startDate, endDate)
                    .eq(DiningOrder::getStatus, 0);
        long canceled = this.count(queryWrapper);
        result.put("canceled", canceled);
        
        // 待确认订单数
        queryWrapper.clear();
        queryWrapper.between(DiningOrder::getOrderDate, startDate, endDate)
                    .eq(DiningOrder::getStatus, 1);
        long pending = this.count(queryWrapper);
        result.put("pending", pending);
        
        // 已确认订单数
        queryWrapper.clear();
        queryWrapper.between(DiningOrder::getOrderDate, startDate, endDate)
                    .eq(DiningOrder::getStatus, 2);
        long confirmed = this.count(queryWrapper);
        result.put("confirmed", confirmed);
        
        return Response.success(result);
    }
}